// 泛型 https://jkchao.github.io/typescript-book-chinese/typings/generices.html#%E5%8A%A8%E6%9C%BA%E5%92%8C%E7%A4%BA%E4%BE%8B
// 目的：解决 类 接口 方法 的复用型、以及对不特定数据类型的支持
// 换句话说，我们可以把相同的类型提取出来为一个变量

// bad 这里就只能返回string类型的数据
const getData1 = (value: string): string => value;

// 那如果我也需要返回number或者其他类型呢？对，我们可以使用any

// 但是通过any来实现的话，相当于放弃了静态类型检查……
const getData2 = (value: any): any => value;

// 也许你会说: 那我再定义一个getData函数 然后设置类型为number不就可以了？ ...你真TM是个人才
// 但是我们希望的是:传入X类型，返回X类型。

// 我们就可以使用 泛型 来完成这个操作 T可以理解为【任意类型】的参数，【调用】这个函数的时候才确定是什么
const getData3 = <T>(value: T): T => value;

// 设定T为string
getData3<string>("123");
// 或者为number
getData3<number>(123);

// 泛型的类
// 最小堆算法
class MinClass {
  public list: number[] = [];

  add(value: number) {
    this.list.push(value);
  }

  min(): number {
    return Math.min(...this.list);
  }
}

const min = new MinClass();
min.add(1);
min.add(2);
console.log(min.min()); // 1
// 但是这个方法 只支持number类型,如果我们后期想增加关于string类型的方法呢？

class MinClas<T> {
  public list: T[] = [];

  add(value: T) {
    this.list.push(value);
  }

  min(): T {
    let min = this.list[0];
    for (let i = 1; i < this.list.length; i++) {
      if (this.list[i] < min) {
        min = this.list[i];
      }
    }
    return min;
  }
}

const min2 = new MinClas<number>();
min2.add(1);
min2.add(2);
console.log(min2.min()); // 1

const min3 = new MinClas<string>();
min3.add("a");
min3.add("b");
console.log(min3.min()); // a
